
package com.jf.cloud.product.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.builder.ExcelWriterBuilder;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.jf.cloud.api.auth.constant.SysTypeEnum;
import com.jf.cloud.api.delivery.feign.DeliveryFeignClient;
import com.jf.cloud.api.delivery.vo.ShopTransportVO;
import com.jf.cloud.api.feign.SearchSpuFeignClient;
import com.jf.cloud.api.product.constant.CategoryLevel;
import com.jf.cloud.api.product.util.ProductLangUtil;
import com.jf.cloud.api.supplier.feign.SupplierDetailFeignClient;
import com.jf.cloud.api.supplier.vo.SupplierApiDetailVO;
import com.jf.cloud.common.constant.Constant;
import com.jf.cloud.common.constant.ExcelConstant;
import com.jf.cloud.common.constant.StatusEnum;
import com.jf.cloud.common.exception.LuckException;
import com.jf.cloud.common.i18n.I18nMessage;
import com.jf.cloud.common.i18n.LanguageEnum;
import com.jf.cloud.common.order.constant.DeliveryType;
import com.jf.cloud.common.product.constant.SpuType;
import com.jf.cloud.common.product.constant.SupplierSpuType;
import com.jf.cloud.common.product.dto.*;
import com.jf.cloud.common.product.vo.*;
import com.jf.cloud.common.product.vo.search.SpuSearchVO;
import com.jf.cloud.common.response.ResponseEnum;
import com.jf.cloud.common.response.ServerResponseEntity;
import com.jf.cloud.common.security.AuthUserContext;
import com.jf.cloud.common.util.Arith;
import com.jf.cloud.common.util.ExcelUtil;
import com.jf.cloud.common.util.Json;
import com.jf.cloud.product.config.OssConfig;
import com.jf.cloud.product.constant.SpuExportError;
import com.jf.cloud.product.dto.SpuPageSearchDTO;
import com.jf.cloud.product.handler.ProductCommentWriteHandler;
import com.jf.cloud.product.mapper.SpuMapper;
import com.jf.cloud.product.model.BrandLang;
import com.jf.cloud.product.service.*;
import com.jf.cloud.product.vo.*;
import ma.glasnost.orika.MapperFacade;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.DecimalFormat;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * spu信息
 *
 * @author zz
 * @date 2020-10-28 15:27:24
 */
@Service
public class SpuExcelServiceImpl implements SpuExcelService {

    @Autowired
    private SpuMapper spuMapper;
    @Autowired
    private SpuService spuService;
    @Autowired
    private SpuExtensionService spuExtensionService;
    @Autowired
    private SkuService skuService;
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private CategoryShopService categoryShopService;
    @Autowired
    private BrandService brandService;
    @Autowired
    private DeliveryFeignClient deliveryFeignClient;
    @Autowired
    private SupplierDetailFeignClient supplierDetailFeignClient;
    @Autowired
    private SearchSpuFeignClient searchSpuFeignClient;
    @Autowired
    private MapperFacade mapperFacade;

    @Autowired
    private OssConfig ossConfig;

    /**
     * 商品显示信息
     */
    public static final String ENABLE = "上架";
    public static final String DISABLE = "下架";
    public static final String OFFLINE = "违规下架";
    public static final String WAIT_AUDIT = "等待审核";
    public static final String PORTION_ENABLE = "部分上架";
    public static final String PORTION_DISABLE = "部分下架";
    //public static final String[] DELIVERY_MODE = {DeliveryType.SAME_CITY.description(), DeliveryType.STATION.description(), "用户自提+同城配送"};
    public static final String[] DELIVERY_MODE = {
            DeliveryType.STATION.description(),
            DeliveryType.SAME_CITY.description(),
            StrUtil.concat(Boolean.TRUE, DeliveryType.STATION.description(), "且", DeliveryType.SAME_CITY.description() )
    };
    public static final String[] SUPPLIER_DELIVERY_MODE = {
            DeliveryType.DELIVERY.description()
    };
    public static final String[] STATUS_MODE = {ENABLE, DISABLE};

    /**
     * 发货方式
     */
    public static final String SUPPLIER_SHIPMENTS = "供应商发货";
    public static final String WAREHOUSE_SHIPMENTS = "仓库发货";
    /**
     * 商品类别 0.实物商品 1. 虚拟商品
     */
    public static final String PHYSICAL_SPU = "实物商品";
    public static final String VIRTUAL_SPU = "虚拟商品";
    public static final String YES = "是";
    public static final String NO = "否";
    public static final String REPEATEDLY = "多次核销";
    public static final String WITHOUT = "无需核销";
    public static final String SINGLE = "单次核销";
    public static final String UNLIMITED = "无限次";
    public static final String CUSTOMIZATION = "自定义";
    public static final String LongTerm = "长期有效";
    public static final String[] MOLD_MODE = {PHYSICAL_SPU, VIRTUAL_SPU};
    public static final String[] WRITE_MODE = {REPEATEDLY, WITHOUT, SINGLE};
    public static final String[] IS_REFUND_MODE = {NO, YES};
    /**
     * 平台分类
     */
    public static final int CATEGORY_INDEX = 7;
    /**
     * 店铺分类
     */
    public static final int SHOP_CATEGORY_INDEX = 8;
    /**
     * 配送方式
     */
    public static final int DELIVERY_MODE_INDEX = 9;
    /**
     * 运费模板
     */
    public static final int DELIVERY_TEMPLATE_INDEX = 10;
    /**
     * 状态
     */
    public static final int STATUS_INDEX = 11;
    /**
     * 商品类别
     */
    public static final int MOLD_INDEX = 12;

    /**
     * 核销次数
     */
    public static final int WRITE_INDEX = 13;

    /**
     * 是否可以退款
     */
    public static final int IS_REFUND_INDEX = 18;

    private static final Logger log = LoggerFactory.getLogger(SpuExcelServiceImpl.class);

    private final static Pattern IMG_URL = Pattern
            .compile(".*?(image/gif|image/jpeg|image/png|image/jpg|image/bmp)");
    private final static Pattern IMG_URL_suffix = Pattern
            .compile(".*?(gif|jpeg|png|jpg|bmp)");

    @Override
    public List<SpuExcelVO> excelSpuList(SpuPageSearchDTO spuDTO) {
        Integer sysType = AuthUserContext.get().getSysType();
        if (Objects.equals(sysType, SysTypeEnum.SUPPLIER.value())) {
            spuDTO.setSupplierId(AuthUserContext.get().getTenantId());
            spuDTO.setSupplierSpuType(SupplierSpuType.YES.value());
            spuDTO.setShopId(-1L);
        } else {
            spuDTO.setShopId(AuthUserContext.get().getTenantId());
        }
        List<SpuExcelVO> list = spuMapper.excelSpuList(spuDTO);
        if (CollUtil.isEmpty(list)) {
            return list;
        }
        Set<Long> categoryIds = new HashSet<>();
        List<Long> spuIds = new ArrayList<>();
        for (SpuExcelVO spuExcelVO : list) {
            spuIds.add(spuExcelVO.getSpuId());
            categoryIds.add(spuExcelVO.getCategoryId());
            categoryIds.add(spuExcelVO.getShopCategoryId());
        }
        // 获取分类列表
        List<CategoryVO> categoryList = categoryService.listByCategoryIds(categoryIds);
        ProductLangUtil.categoryList(categoryList);
        Map<Long, CategoryVO> categoryMap = categoryList.stream().collect(Collectors.toMap(CategoryVO::getCategoryId, c -> c));
        // 获取sku信息列表
        List<SpuExcelVO> skuList = skuService.excelSkuList(spuIds);
        Map<Long, List<SpuExcelVO>> skuMap = skuList.stream().collect(Collectors.groupingBy(SpuExcelVO::getSpuId));
        List<SpuExcelVO> spuExcelList = new ArrayList<>();
        // 店铺运费模板
        ServerResponseEntity<List<ShopTransportVO>> response = deliveryFeignClient.listTransportByShopId(Objects.equals(sysType, SysTypeEnum.SUPPLIER.value()) ? spuDTO.getSupplierId() : spuDTO.getShopId());
        if (!Objects.equals(response.getCode(), ResponseEnum.OK.value())) {
            throw new LuckException(response.getMsg());
        }
        Map<Long, String> transportMap = response.getData().stream().collect(Collectors.toMap(ShopTransportVO::getTransportId, ShopTransportVO::getTransName));

        int index = 1;
        for (SpuExcelVO spuExcelVO : list) {
            List<SpuExcelVO> skuData = skuMap.get(spuExcelVO.getSpuId());
            if (CollUtil.isEmpty(skuData)) {
                continue;
            }
            spuExcelVO.setSeq(String.valueOf(index));
            spuExcelVO.setDeliveryTemplate(transportMap.get(spuExcelVO.getDeliveryTemplateId()));
            // 状态
            if (Objects.equals(spuExcelVO.getStatus(), StatusEnum.ENABLE.value().toString())) {
                spuExcelVO.setStatus(ENABLE);
            } else if (Objects.equals(spuExcelVO.getStatus(), StatusEnum.DISABLE.value().toString())) {
                spuExcelVO.setStatus(DISABLE);
            } else if (Objects.equals(spuExcelVO.getStatus(), StatusEnum.OFFLINE.value().toString())) {
                spuExcelVO.setStatus(OFFLINE);
            } else if (Objects.equals(spuExcelVO.getStatus(), StatusEnum.WAIT_AUDIT.value().toString())) {
                spuExcelVO.setStatus(WAIT_AUDIT);
            }
            // 虚拟商品信息
            spuExcelVO.setSpuMold(StrUtil.equals(spuExcelVO.getSpuMold(), "1") ? VIRTUAL_SPU : PHYSICAL_SPU);
            String isRefundStr = spuExcelVO.getIsRefund() == null ? "" : (StrUtil.equals(spuExcelVO.getIsRefund(), "1") ? YES : NO);
            spuExcelVO.setIsRefund(isRefundStr);
            //虚拟商品的核销信息
            if (StrUtil.equals(spuExcelVO.getSpuMold(), VIRTUAL_SPU)) {
                if (StrUtil.equals(spuExcelVO.getWriteOffNum(), "0")) {
                    spuExcelVO.setWriteOffNum(WITHOUT);
                } else if (Objects.equals(spuExcelVO.getWriteOffNum(), "-1")) {
                    spuExcelVO.setWriteOffNum(REPEATEDLY);
                } else if (Objects.equals(spuExcelVO.getWriteOffNum(), "1")) {
                    spuExcelVO.setWriteOffNum(SINGLE);
                }
                spuExcelVO.setWriteOffMultipleCount(StrUtil.equals(spuExcelVO.getWriteOffMultipleCount(), "-1") ? UNLIMITED : spuExcelVO.getWriteOffMultipleCount());
                if (StrUtil.equals(spuExcelVO.getWriteOffTime(), "-1")) {
                    spuExcelVO.setWriteOffTime(LongTerm);
                    spuExcelVO.setWriteOffStart(null);
                    spuExcelVO.setWriteOffEnd(null);
                } else {
                    spuExcelVO.setWriteOffTime(StrUtil.equals(spuExcelVO.getWriteOffTime(), null) ? "" : spuExcelVO.getWriteOffTime() + "天");
                }
            } else {
                spuExcelVO.setWriteOffNum("");
            }
            // 配送方式
            SpuVO.DeliveryModeVO deliveryModeVO = Json.parseObject(spuExcelVO.getDeliveryMode(), SpuVO.DeliveryModeVO.class);
            String delivery = getDelivery(deliveryModeVO);
            if (Objects.equals(spuExcelVO.getSpuMold(), VIRTUAL_SPU) || Objects.equals(spuExcelVO.getSpuType(), SpuType.ACTIVE.value())) {
                spuExcelVO.setDeliveryMode(DeliveryType.NOT_DELIVERY.description() + Constant.COMMA);
            } else {
                spuExcelVO.setDeliveryMode(delivery);
            }
            handleSpuExcelInfo(categoryMap, skuData, spuExcelList, spuExcelVO);
            index++;
        }
        return spuExcelList;
    }

    private void handleSpuExcelInfo(Map<Long, CategoryVO> categoryMap, List<SpuExcelVO> skuData, List<SpuExcelVO> spuExcelList, SpuExcelVO spuExcelVO) {

        String brandName = null;
        if (CollUtil.isNotEmpty(spuExcelVO.getBrandLangList())) {
            BrandLangVO brandLang = ProductLangUtil.handelBrandLang(spuExcelVO.getBrandLangList());
            brandName = brandLang.getName();
        }
        // 名称、卖点
        for (SpuLangVO spuLangVO : spuExcelVO.getSpuLangList()) {
            if (Objects.equals(spuLangVO.getLang(), LanguageEnum.LANGUAGE_ZH_CN.getLang())) {
                spuExcelVO.setNameZh(spuLangVO.getSpuName());
                spuExcelVO.setSellingPointZh(spuLangVO.getSellingPoint());
            }
        }
        String categoryName = null;
        String shopCategoryName = null;
        // 平台分类
        CategoryVO categoryVO = categoryMap.get(spuExcelVO.getCategoryId());
        if (Objects.nonNull(categoryVO)) {
            categoryName = categoryVO.getName();
        }
        // 店铺分类
        CategoryVO shopCategoryVO = categoryMap.get(spuExcelVO.getShopCategoryId());
        if (Objects.nonNull(shopCategoryVO)) {
            shopCategoryName = shopCategoryVO.getName();
        }
        String delivery = spuExcelVO.getDeliveryMode();
        delivery = delivery.substring(0, delivery.length() - 1);
        String resourceUrl = ossConfig.getResourcesUrl();
        for (SpuExcelVO spuExcel : skuData) {
            spuExcel.setPriceFee(conversionPrices(spuExcel.getPriceFee()));
            spuExcel.setMarketPriceFee(conversionPrices(spuExcel.getMarketPriceFee()));
            spuExcel.setSeq(spuExcelVO.getSeq());
            spuExcel.setDeliveryTemplate(spuExcelVO.getDeliveryTemplate());
            spuExcel.setBrandName(brandName);
            spuExcel.setNameZh(spuExcelVO.getNameZh());
//            spuExcel.setNameEn(spuExcelVO.getNameEn());
            spuExcel.setSellingPointZh(spuExcelVO.getSellingPointZh());
//            spuExcel.setSellingPointEn(spuExcelVO.getSellingPointEn());
            spuExcel.setCategoryName(categoryName);
            spuExcel.setShopCategoryName(shopCategoryName);
            spuExcel.setDeliveryMode(delivery);
            spuExcel.setStatus(spuExcelVO.getStatus());
            spuExcel.setSpuMold(spuExcelVO.getSpuMold());
            spuExcel.setWriteOffNum(spuExcelVO.getWriteOffNum());
            spuExcel.setWriteOffMultipleCount(spuExcelVO.getWriteOffMultipleCount());
            spuExcel.setWriteOffTime(spuExcelVO.getWriteOffTime());
            spuExcel.setWriteOffStart(spuExcelVO.getWriteOffStart());
            spuExcel.setWriteOffEnd(spuExcelVO.getWriteOffEnd());
            spuExcel.setIsRefund(spuExcelVO.getIsRefund());
            spuExcel.setVirtualRemark(spuExcelVO.getVirtualRemark());
            spuExcel.setImgs(ObjectUtils.isEmpty(spuExcel.getImgs()) ? spuExcelVO.getMainImgUrl() : null);
            // 补充图片，视频资源域名地址
            if (!ObjectUtils.isEmpty(spuExcel.getImgs())) {
                String[] imgArr = spuExcel.getImgs().split(ExcelConstant.COMMA_SPLIT);
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < imgArr.length; i++) {
                    if (!imgArr[i].startsWith(ExcelConstant.URL_PREFIX)) {
                        imgArr[i] = resourceUrl + imgArr[i];
                    }
                    sb.append(imgArr[i]).append(ExcelConstant.COMMA_SPLIT);
                }
                spuExcel.setImgs(sb.substring(0, sb.toString().length() - 1));
            }
            if (!ObjectUtils.isEmpty(spuExcel.getVideo())
                    && !spuExcel.getVideo().startsWith(ExcelConstant.URL_PREFIX)) {
                spuExcel.setVideo(resourceUrl + spuExcelVO.getVideo());
            }
            spuExcelList.add(spuExcel);
        }
    }

    @Override
    public void exportExcel(List<SpuExcelVO> spuList, Map<Integer, List<String>> errorMap) {
        if (CollUtil.isEmpty(spuList)) {
            addSpuExcelError(errorMap, SpuExportError.OTHER, "导入文件为空");
            return;
        }
        for (SpuExcelVO spuExcelVO : spuList) {
            if (Objects.isNull(spuExcelVO.getSeq())) {
                addSpuExcelError(errorMap, SpuExportError.OTHER, "编号不能为空");
                return;
            }
            if (StrUtil.isNotBlank(spuExcelVO.getImgs())) {
                String[] split = spuExcelVO.getImgs().split(",");
                if (!checkPic(split, errorMap)) {
                    return;
                }
            }
            if (StrUtil.isNotBlank(spuExcelVO.getVideo())) {
                if (!checkVideo(spuExcelVO.getVideo(), errorMap)) {
                    return;
                }
            }
        }

        Integer sysType = AuthUserContext.get().getSysType();
        Long shopId = AuthUserContext.get().getTenantId();
        Set<Long> brandIds = new HashSet<>();
        // 平台分类
        Map<String, Long> categoryMap = getCategoryList(Constant.PLATFORM_SHOP_ID);
        // 店铺分类
        Map<String, Long> shopCategoryMap = getCategoryList(shopId);
        //供应商没有店铺分类
        if (!Objects.equals(sysType, SysTypeEnum.SUPPLIER.value()) && MapUtil.isEmpty(shopCategoryMap)) {
            addSpuExcelError(errorMap, SpuExportError.OTHER, "请先创建店铺分类");
            return;
        }
        // 运费模板
        ServerResponseEntity<List<ShopTransportVO>> response = deliveryFeignClient.listTransportByShopId(shopId);
        Map<String, Long> transportMap = response.getData().stream().collect(Collectors.toMap(ShopTransportVO::getTransName, ShopTransportVO::getTransportId));
        if (MapUtil.isEmpty(transportMap)) {
            addSpuExcelError(errorMap, SpuExportError.OTHER, "请先创建运费模板");
            return;
        }
        // 品牌
        Set<String> brandNames = new HashSet<>();
        for (SpuExcelVO spuExcel : spuList) {
            brandNames.add(spuExcel.getBrandName());
        }
        List<BrandLang> brandList = brandService.listBrandLangByBrandNames(brandNames, shopId);
        Map<String, List<BrandLang>> brandMap = brandList.stream().collect(Collectors.groupingBy(BrandLang::getName));
        Map<String, List<SpuExcelVO>> spuMap = spuList.stream().collect(Collectors.groupingBy(SpuExcelVO::getSeq));
        for (String seq : spuMap.keySet()) {
            List<SpuExcelVO> spuExcelList = spuMap.get(seq);
            SpuDTO spu = new SpuDTO();
            spu.setShopId(shopId);
            try {
                loadSpuData(spuExcelList, spu, categoryMap, shopCategoryMap, transportMap, brandMap, errorMap);
            } catch (Exception e) {
                addSpuExcelError(errorMap, SpuExportError.PRODUCT_DATA, e.getMessage());
                continue;
            }
            if (Objects.nonNull(spu.getBrandId())) {
                brandIds.add(spu.getBrandId());
            }
        }
        brandService.updateSpuCountByBrandIds(brandIds);
    }

    private boolean checkVideo(String video, Map<Integer, List<String>> errorMap) {
        try {
            URL url = new URL(video);
            String videoName = "video/mp4";
            String map4 = ".map4";
            if (!Objects.equals(url.openConnection().getHeaderField(Constant.CONTENT_TYPE), videoName) || video.endsWith(map4)) {
                addSpuExcelError(errorMap, SpuExportError.OTHER, "上传视频格式错误");
                return false;
            }
        } catch (IOException e) {
            log.error("视频格式判断出错：{}", e.getMessage());
        }
        int length = getFileLength(video);
        int MB = 1024 * 1024;//定义MB的计算常量
        DecimalFormat df = new DecimalFormat("0.00");
        float lengthByMB = Float.parseFloat(df.format(length / (float) MB));
        if (lengthByMB > Constant.FIFTY) {
            addSpuExcelError(errorMap, SpuExportError.OTHER, "上传视频大小超出限制");
            return false;
        }
        return true;
    }

    private int getFileLength(String url1) {
        int length = 0;
        URL url;
        try {
            url = new URL(url1);
            HttpURLConnection urlcon = (HttpURLConnection) url.openConnection();
            //根据响应获取文件大小
            length = urlcon.getContentLength();
            urlcon.disconnect();
        } catch (MalformedURLException e) {
            e.getMessage();
        } catch (IOException e) {
            e.getMessage();
        }
        return length;
    }

    private boolean checkPic(String[] split, Map<Integer, List<String>> errorMap) {
        if (split.length > Constant.NINE) {
            addSpuExcelError(errorMap, SpuExportError.OTHER, "最多上传9张图片");
            return false;
        }
        for (String s : split) {
            if (!isImgUrl(s)) {
                addSpuExcelError(errorMap, SpuExportError.OTHER, "上传图片格式错误");
                return false;
            }
        }
        return true;
    }

    private boolean isImgUrl(String url) {
        if (url == null || url.trim().length() == 0) {
            return false;
        }
        String suffix = url.substring(url.lastIndexOf("."));
        try {
            return IMG_URL_suffix.matcher(suffix).matches() || IMG_URL.matcher(new URL(url).openConnection().getHeaderField("content-type")).matches();
        } catch (IOException e) {
            log.error("图片格式判断出错:{}", e.getMessage());
        }
        return false;
    }

    private void addSpuExcelError(Map<Integer, List<String>> errorMap, SpuExportError spuExportError, String error) {
        List list = errorMap.get(spuExportError.value());
        if (CollUtil.isEmpty(list)) {
            list = new ArrayList();
            errorMap.put(spuExportError.value(), list);
        }
        list.add(error);
    }

    private Map<String, Long> getCategoryList(Long shopId) {
        List<CategoryVO> categoryList;
        if (Objects.equals(shopId, Constant.PLATFORM_SHOP_ID)) {
            categoryList = categoryService.getShopSigningCategoryAndLangInfo(AuthUserContext.get().getTenantId());
        } else {
            categoryList = categoryService.listAndLangInfoByShopId(shopId);
        }
        categoryList.sort(Comparator.comparing(CategoryVO::getSeq).reversed().thenComparing(CategoryVO::getCategoryId));
        Map<String, Long> categoryNameMap = new HashMap<>(categoryList.size());
        Map<String, Long> categoryNameEnMap = new HashMap<>(categoryList.size());
        for (CategoryVO categoryVO : categoryList) {
            boolean isParentCategory = Objects.equals(categoryVO.getLevel(), CategoryLevel.First.value()) ||
                    (Objects.equals(shopId, Constant.PLATFORM_SHOP_ID) && Objects.equals(categoryVO.getLevel(), CategoryLevel.SECOND.value()));
            if (isParentCategory) {
                continue;
            }
            for (CategoryLangVO categoryLangVO : categoryVO.getCategoryLangList()) {
                String name = categoryLangVO.getName();
                if (Objects.equals(categoryLangVO.getLang(), LanguageEnum.LANGUAGE_ZH_CN.getLang()) && !categoryNameMap.containsKey(name)) {
                    categoryNameMap.put(name, categoryVO.getCategoryId());
                } else if (Objects.equals(categoryLangVO.getLang(), LanguageEnum.LANGUAGE_EN.getLang()) && !categoryNameMap.containsKey(name)) {
                    categoryNameEnMap.put(name, categoryVO.getCategoryId());
                }
            }
        }
        for (String key : categoryNameEnMap.keySet()) {
            if (!categoryNameMap.containsKey(key)) {
                categoryNameMap.put(key, categoryNameEnMap.get(key));
            }
        }
        return categoryNameMap;
    }

    @Override
    public String spuExportError(Map<Integer, List<String>> errorMap) {
        StringBuilder info = new StringBuilder();
        for (Integer key : errorMap.keySet()) {
            List<String> list = errorMap.get(key);
            SpuExportError spuExportError = SpuExportError.instance(key);
            if (Objects.equals(spuExportError, SpuExportError.OTHER)) {
                info.append(list.toString() + "\n");
                continue;
            }
            info.append(spuExportError.errorInfo() + list.toString() + "\n");
        }
        return info.toString();
    }

    @Override
    public void downloadModel(HttpServletResponse response) {
        Long shopId = AuthUserContext.get().getTenantId();
        List<SpuExcelVO> list = new ArrayList<>();
        list.add(new SpuExcelVO());
        Map<Integer, String[]> map = new HashMap<>(8);
        if (Objects.equals(AuthUserContext.get().getSysType(), SysTypeEnum.SUPPLIER.value())) {
            map.put(DELIVERY_MODE_INDEX - 1, SUPPLIER_DELIVERY_MODE);
            map.put(STATUS_INDEX - 1, STATUS_MODE);
        } else {
            map.put(DELIVERY_MODE_INDEX, DELIVERY_MODE);
            map.put(STATUS_INDEX, STATUS_MODE);
            map.put(MOLD_INDEX, MOLD_MODE);
            map.put(WRITE_INDEX, WRITE_MODE);
            map.put(IS_REFUND_INDEX, IS_REFUND_MODE);
        }

        ServerResponseEntity<List<ShopTransportVO>> responseEntity = deliveryFeignClient.listTransportByShopId(shopId);
        List<ShopTransportVO> data = responseEntity.getData();
        if (CollUtil.isNotEmpty(data)) {
            String[] transNames = new String[data.size()];
            for (int i = 0; i < data.size(); i++) {
                ShopTransportVO transport = data.get(i);
                transNames[i] = transport.getTransName();
            }
            if (Objects.equals(AuthUserContext.get().getSysType(), SysTypeEnum.SUPPLIER.value())) {
                map.put(DELIVERY_TEMPLATE_INDEX - 1, transNames);
            } else {
                map.put(DELIVERY_TEMPLATE_INDEX, transNames);
            }

        }
        // 平台分类
        List<CategoryShopVO> categoryShopList = categoryShopService.listByShopId(shopId, AuthUserContext.get().getSysType(), I18nMessage.getLang());
        List<String> categoryNames = categoryShopList.stream().map(CategoryShopVO::getName).collect(Collectors.toList());
        map.put(CATEGORY_INDEX, categoryNames.toArray(new String[categoryNames.size()]));
        //店铺分类
        List<CategoryVO> shopCategoryList = categoryService.listEnable(shopId);
        //判断店铺分类是否为空
        if (!Objects.equals(AuthUserContext.get().getSysType(), SysTypeEnum.SUPPLIER.value())) {
            if (shopCategoryList.size() != 0) {
                ProductLangUtil.categoryList(shopCategoryList);
                List<String> shopCategoryNames = shopCategoryList.stream().map(CategoryVO::getName).collect(Collectors.toList());
                map.put(SHOP_CATEGORY_INDEX, shopCategoryNames.toArray(new String[shopCategoryNames.size()]));
            }
        }
        ExcelWriter excelWriter = null;
        try {
            // 先执行合并策略
            ExcelWriterBuilder excelWriterMerge = ExcelUtil.getExcelWriterMerge(response, SpuExcelVO.EXCEL_NAME, SpuExcelVO.MERGE_ROW_INDEX, SpuExcelVO.MERGE_COLUMN_INDEX);
            excelWriter = ExcelUtil.getExcelModel(excelWriterMerge, map, Constant.START_ROW).build();

            // 业务代码
            if (CollUtil.isNotEmpty(list)) {
                // 进行写入操作
                WriteSheet sheetWriter = new WriteSheet();
                if (Objects.equals(AuthUserContext.get().getSysType(), SysTypeEnum.SUPPLIER.value())) {
                    sheetWriter = EasyExcel.writerSheet(SupplierProdExcelVO.SHEET_NAME).head(SupplierProdExcelVO.class)
                            .registerWriteHandler(new ProductCommentWriteHandler(SysTypeEnum.SUPPLIER.value())).build();
                } else {
                    sheetWriter = EasyExcel.writerSheet(SpuExcelVO.SHEET_NAME).head(SpuExcelVO.class)
                            .registerWriteHandler(new ProductCommentWriteHandler(SysTypeEnum.MULTISHOP.value())).build();
                }

                excelWriter.write(list, sheetWriter);
            }
        } catch (Exception e) {
            log.error("导出excel失败", e);
        } finally {
            // 千万别忘记finish 会帮忙关闭流
            if (excelWriter != null) {
                excelWriter.finish();
            }
        }
    }

    @Override
    public List<SupplierSpuExcelVO> excelSupplierSpuList(SpuPageSearchDTO spuDTO) {
        spuDTO.setShopId(AuthUserContext.get().getTenantId());
        List<SupplierSpuExcelVO> list = spuMapper.excelSupplierSpuList(spuDTO);
        if (CollUtil.isEmpty(list)) {
            return list;
        }
        Set<Long> categoryIds = new HashSet<>();
        List<Long> spuIds = new ArrayList<>();
        for (SupplierSpuExcelVO supplierSpuExcelVO : list) {
            spuIds.add(supplierSpuExcelVO.getSpuId());
            categoryIds.add(supplierSpuExcelVO.getCategoryId());
            categoryIds.add(supplierSpuExcelVO.getShopCategoryId());
        }
        // 获取分类列表
        List<CategoryVO> categoryList = categoryService.listByCategoryIds(categoryIds);
        ProductLangUtil.categoryList(categoryList);
        Map<Long, CategoryVO> categoryMap = categoryList.stream().collect(Collectors.toMap(CategoryVO::getCategoryId, c -> c));
        // 获取sku信息列表
        List<SupplierSpuExcelVO> skuList = skuService.excelSupplierSkuList(spuIds);
        Map<Long, List<SupplierSpuExcelVO>> skuMap = skuList.stream().collect(Collectors.groupingBy(SupplierSpuExcelVO::getSpuId));
        List<SupplierSpuExcelVO> spuExcelList = new ArrayList<>();
        // 店铺运费模板
        ServerResponseEntity<List<ShopTransportVO>> response = deliveryFeignClient.listTransportByShopId(spuDTO.getShopId());
        if (!Objects.equals(response.getCode(), ResponseEnum.OK.value())) {
            throw new LuckException(response.getMsg());
        }
        Map<Long, String> transportMap = response.getData().stream().collect(Collectors.toMap(ShopTransportVO::getTransportId, ShopTransportVO::getTransName));

        //供应商名称
        List<Long> supplierIds = list.stream().map(e -> e.getSupplierId()).collect(Collectors.toList());
        ServerResponseEntity<List<SupplierApiDetailVO>> listServerResponseEntity = supplierDetailFeignClient.listBySupplierIds(supplierIds);
        Map<Long, String> supplierName = listServerResponseEntity.getData().stream().collect(Collectors.toMap(SupplierApiDetailVO::getSupplierId, SupplierApiDetailVO::getSupplierName));
        int index = 1;
        for (SupplierSpuExcelVO supplierSpuExcelVO : list) {
            List<SupplierSpuExcelVO> skuData = skuMap.get(supplierSpuExcelVO.getSpuId());
            if (CollUtil.isEmpty(skuData)) {
                continue;
            }
            //供应商名称
            supplierSpuExcelVO.setSupplierName(supplierName.get(supplierSpuExcelVO.getSupplierId()));
            //发货方式
            Integer supplierDeliveryType = supplierSpuExcelVO.getSupplierDeliveryType();
            supplierSpuExcelVO.setSupplierDelivery(supplierDeliveryType == 1 ? SUPPLIER_SHIPMENTS : WAREHOUSE_SHIPMENTS);
            //代销商品状态
            Integer status = Integer.valueOf(supplierSpuExcelVO.getStatus());
            Integer skuChoiceStatus = supplierSpuExcelVO.getSkuChoiceStatus();
            if (status == 1) {
                supplierSpuExcelVO.setCommissionSpuStatus(skuChoiceStatus == 1 ? ENABLE : PORTION_ENABLE);
            }
            if (status == 0) {
                supplierSpuExcelVO.setCommissionSpuStatus(skuChoiceStatus == 1 ? DISABLE : PORTION_DISABLE);
            }
            supplierSpuExcelVO.setSeq(String.valueOf(index));
            supplierSpuExcelVO.setDeliveryTemplate(transportMap.get(supplierSpuExcelVO.getDeliveryTemplateId()));
            // 状态
            if (Objects.equals(supplierSpuExcelVO.getStatus(), StatusEnum.ENABLE.value().toString())) {
                supplierSpuExcelVO.setStatus(ENABLE);
            } else if (Objects.equals(supplierSpuExcelVO.getStatus(), StatusEnum.DISABLE.value().toString())) {
                supplierSpuExcelVO.setStatus(DISABLE);
            } else if (Objects.equals(supplierSpuExcelVO.getStatus(), StatusEnum.OFFLINE.value().toString())) {
                supplierSpuExcelVO.setStatus(OFFLINE);
            } else if (Objects.equals(supplierSpuExcelVO.getStatus(), StatusEnum.WAIT_AUDIT.value().toString())) {
                supplierSpuExcelVO.setStatus(WAIT_AUDIT);
            }
            // 配送方式
            SpuVO.DeliveryModeVO deliveryModeVO = Json.parseObject(supplierSpuExcelVO.getDeliveryMode(), SpuVO.DeliveryModeVO.class);
            String delivery = getDelivery(deliveryModeVO);
            supplierSpuExcelVO.setDeliveryMode(delivery);
            handleSupplierSpuExcelInfo(categoryMap, skuData, spuExcelList, supplierSpuExcelVO);
            index++;
        }
        return spuExcelList;
    }

    @Override
    public List<PlatformSpuExcelVO> excelPlatformSpuList(ProductSearchDTO productSearchDTO) {
        ServerResponseEntity<List<SpuSearchVO>> responseEntity = searchSpuFeignClient.listExcelPlatformSpu(productSearchDTO);
        if (!responseEntity.isSuccess()) {
            throw new LuckException(responseEntity.getMsg());
        }
        List<SpuSearchVO> spuEsList = responseEntity.getData();
        if (CollUtil.isEmpty(spuEsList)) {
            return new ArrayList<>();
        }
        List<Long> spuIds = spuEsList.stream().map(SpuSearchVO::getSpuId).collect(Collectors.toList());
        Map<Long, SpuSearchVO> esSpuMap = spuEsList.stream().collect(Collectors.toMap(SpuSearchVO::getSpuId, c -> c));
        List<PlatformSpuExcelVO> platformSpuExcelVOList = spuMapper.listPlatformSpuExcel(spuIds);
        Set<Long> categoryIds = new HashSet<>();
        Set<Long> deliveryTemplateIds = new HashSet<>();
        for (PlatformSpuExcelVO spuExcelVO : platformSpuExcelVOList) {
            categoryIds.add(spuExcelVO.getCategoryId());
            categoryIds.add(spuExcelVO.getShopCategoryId());
            deliveryTemplateIds.add(spuExcelVO.getDeliveryTemplateId());
        }
        // 获取分类列表
        List<CategoryVO> categoryList = categoryService.listByCategoryIds(categoryIds);
        ProductLangUtil.categoryList(categoryList);
        Map<Long, CategoryVO> categoryMap = categoryList.stream().collect(Collectors.toMap(CategoryVO::getCategoryId, c -> c));

        List<PlatformSpuExcelVO> skuExcelList = mapperFacade.mapAsList(skuService.excelSkuList(spuIds), PlatformSpuExcelVO.class);
        Map<Long, List<PlatformSpuExcelVO>> skuMap = skuExcelList.stream().collect(Collectors.groupingBy(PlatformSpuExcelVO::getSpuId));
        List<PlatformSpuExcelVO> spuExcelList = new ArrayList<>();
        // 店铺运费模板
        ServerResponseEntity<List<ShopTransportVO>> response = deliveryFeignClient.listTransportByIds(new ArrayList<>(deliveryTemplateIds));
        if (!response.isSuccess()) {
            throw new LuckException(response.getMsg());
        }
        Map<Long, String> transportMap = response.getData().stream().collect(Collectors.toMap(ShopTransportVO::getTransportId, ShopTransportVO::getTransName));

        int index = 1;
        for (PlatformSpuExcelVO spuExcelVO : platformSpuExcelVOList) {
            List<PlatformSpuExcelVO> skuData = skuMap.get(spuExcelVO.getSpuId());
            SpuSearchVO spuSearchVO = esSpuMap.get(spuExcelVO.getSpuId());
            if (CollUtil.isEmpty(skuData)) {
                continue;
            }
            spuExcelVO.setSeq(String.valueOf(index));
            spuExcelVO.setShopName(Objects.isNull(spuSearchVO.getShopName()) ? spuSearchVO.getSupplierName() : spuSearchVO.getShopName());
            spuExcelVO.setDeliveryTemplate(transportMap.get(spuExcelVO.getDeliveryTemplateId()));
            spuExcelVO.setSpuTypeName(SpuType.getSpuTypeName(spuSearchVO.getSpuType()));
            // 状态
            if (Objects.equals(spuSearchVO.getSpuStatus(), StatusEnum.ENABLE.value())) {
                spuExcelVO.setStatus(ENABLE);
            } else if (Objects.equals(spuSearchVO.getSpuStatus(), StatusEnum.DISABLE.value())) {
                spuExcelVO.setStatus(DISABLE);
            } else if (Objects.equals(spuSearchVO.getSpuStatus(), StatusEnum.OFFLINE.value())) {
                spuExcelVO.setStatus(OFFLINE);
            } else if (Objects.equals(spuSearchVO.getSpuStatus(), StatusEnum.WAIT_AUDIT.value())) {
                spuExcelVO.setStatus(WAIT_AUDIT);
            }
            // 虚拟商品信息
            spuExcelVO.setSpuMold(Objects.equals(spuSearchVO.getSpuMold(), 1) ? VIRTUAL_SPU : PHYSICAL_SPU);
            //虚拟商品的核销信息
            if (StrUtil.equals(spuExcelVO.getSpuMold(), VIRTUAL_SPU)) {
                if (StrUtil.equals(spuExcelVO.getWriteOffNum(), "0")) {
                    spuExcelVO.setWriteOffNum(WITHOUT);
                } else if (Objects.equals(spuExcelVO.getWriteOffNum(), "-1")) {
                    spuExcelVO.setWriteOffNum(REPEATEDLY);
                } else if (Objects.equals(spuExcelVO.getWriteOffNum(), "1")) {
                    spuExcelVO.setWriteOffNum(SINGLE);
                }
                spuExcelVO.setWriteOffMultipleCount(StrUtil.equals(spuExcelVO.getWriteOffMultipleCount(), "-1") ? UNLIMITED : spuExcelVO.getWriteOffMultipleCount());
                spuExcelVO.setWriteOffTime(StrUtil.equals(spuExcelVO.getWriteOffTime(), null) ? "" : spuExcelVO.getWriteOffTime() + "天");
            }
            spuExcelVO.setIsRefund(StrUtil.equals(spuExcelVO.getIsRefund(), "1") ? YES : NO);
            spuExcelVO.setIsTop(StrUtil.equals(spuExcelVO.getIsTop(), "1") ? YES : NO);
            // 配送方式
            SpuVO.DeliveryModeVO deliveryModeVO = Json.parseObject(spuExcelVO.getDeliveryMode(), SpuVO.DeliveryModeVO.class);
            String delivery = getDelivery(deliveryModeVO);
            if (Objects.equals(spuExcelVO.getSpuMold(), VIRTUAL_SPU) || Objects.equals(spuExcelVO.getSpuType(), SpuType.ACTIVE.value())) {
                spuExcelVO.setDeliveryMode(DeliveryType.NOT_DELIVERY.description() + Constant.COMMA);
            } else {
                spuExcelVO.setDeliveryMode(delivery);
            }
            handlePlatformSpuExcelInfo(categoryMap, skuData, spuExcelList, spuExcelVO);
            index++;
        }
        return spuExcelList;
    }

    private String getDelivery(SpuVO.DeliveryModeVO deliveryModeVO) {
        String delivery = "";
        if (deliveryModeVO.getHasUserPickUp()) {
            delivery = DeliveryType.STATION.description() + Constant.COMMA;
        }
        if (deliveryModeVO.getHasCityDelivery()) {
            delivery = delivery + DeliveryType.SAME_CITY.description() + Constant.COMMA;
        }
        if (deliveryModeVO.getHasShopDelivery()) {
            delivery = delivery + DeliveryType.DELIVERY.description() + Constant.COMMA;
        }
        return delivery;
    }

    private void handlePlatformSpuExcelInfo(Map<Long, CategoryVO> categoryMap, List<PlatformSpuExcelVO> skuData, List<PlatformSpuExcelVO> spuExcelList, PlatformSpuExcelVO spuExcelVO) {

        String brandName = null;
        if (CollUtil.isNotEmpty(spuExcelVO.getBrandLangList())) {
            BrandLangVO brandLang = ProductLangUtil.handelBrandLang(spuExcelVO.getBrandLangList());
            brandName = brandLang.getName();
        }
        // 名称、卖点
        for (SpuLangVO spuLangVO : spuExcelVO.getSpuLangList()) {
            if (Objects.equals(spuLangVO.getLang(), LanguageEnum.LANGUAGE_ZH_CN.getLang())) {
                spuExcelVO.setNameZh(spuLangVO.getSpuName());
                spuExcelVO.setSellingPointZh(spuLangVO.getSellingPoint());
            }
        }
        String categoryName = null;
        String shopCategoryName = null;
        // 平台分类
        CategoryVO categoryVO = categoryMap.get(spuExcelVO.getCategoryId());
        if (Objects.nonNull(categoryVO)) {
            categoryName = categoryVO.getName();
        }
        // 店铺分类
        CategoryVO shopCategoryVO = categoryMap.get(spuExcelVO.getShopCategoryId());
        if (Objects.nonNull(shopCategoryVO)) {
            shopCategoryName = shopCategoryVO.getName();
        }
        String delivery = spuExcelVO.getDeliveryMode();
        delivery = delivery.substring(0, delivery.length() - 1);
        for (PlatformSpuExcelVO spuExcel : skuData) {
            spuExcel.setPriceFee(conversionPrices(spuExcel.getPriceFee()));
            spuExcel.setShopName(spuExcelVO.getShopName());
            spuExcel.setSpuTypeName(spuExcelVO.getSpuTypeName());
            spuExcel.setMarketPriceFee(conversionPrices(spuExcel.getMarketPriceFee()));
            spuExcel.setSeq(spuExcelVO.getSeq());
            spuExcel.setWaterSoldNum(spuExcelVO.getWaterSoldNum());
            spuExcel.setDeliveryTemplate(spuExcelVO.getDeliveryTemplate());
            spuExcel.setBrandName(brandName);
            spuExcel.setNameZh(spuExcelVO.getNameZh());
//            spuExcel.setNameEn(spuExcelVO.getNameEn());
            spuExcel.setSellingPointZh(spuExcelVO.getSellingPointZh());
//            spuExcel.setSellingPointEn(spuExcelVO.getSellingPointEn());
            spuExcel.setCategoryName(categoryName);
            spuExcel.setShopCategoryName(shopCategoryName);
            spuExcel.setDeliveryMode(delivery);
            spuExcel.setStatus(spuExcelVO.getStatus());
            spuExcel.setSpuMold(spuExcelVO.getSpuMold());
            spuExcel.setWriteOffNum(spuExcelVO.getWriteOffNum());
            spuExcel.setWriteOffMultipleCount(spuExcelVO.getWriteOffMultipleCount());
            spuExcel.setWriteOffTime(spuExcelVO.getWriteOffTime());
            spuExcel.setWriteOffStart(spuExcelVO.getWriteOffStart());
            spuExcel.setWriteOffEnd(spuExcelVO.getWriteOffEnd());
            spuExcel.setIsRefund(spuExcelVO.getIsRefund());
            spuExcel.setIsTop(spuExcelVO.getIsTop());
            spuExcel.setVirtualRemark(spuExcelVO.getVirtualRemark());
            spuExcelList.add(spuExcel);
        }
    }

    private void handleSupplierSpuExcelInfo(Map<Long, CategoryVO> categoryMap, List<SupplierSpuExcelVO> skuData, List<SupplierSpuExcelVO> spuExcelList, SupplierSpuExcelVO spuExcelVO) {

        String brandName = null;
        if (CollUtil.isNotEmpty(spuExcelVO.getBrandLangList())) {
            BrandLangVO brandLang = ProductLangUtil.handelBrandLang(spuExcelVO.getBrandLangList());
            brandName = brandLang.getName();
        }
        // 名称、卖点
        for (SpuLangVO spuLangVO : spuExcelVO.getSpuLangList()) {
            if (Objects.equals(spuLangVO.getLang(), LanguageEnum.LANGUAGE_ZH_CN.getLang())) {
                spuExcelVO.setNameZh(spuLangVO.getSpuName());
                spuExcelVO.setSellingPointZh(spuLangVO.getSellingPoint());
            }
        }
        String categoryName = null;
        String shopCategoryName = null;
        // 平台分类
        CategoryVO categoryVO = categoryMap.get(spuExcelVO.getCategoryId());
        if (Objects.nonNull(categoryVO)) {
            categoryName = categoryVO.getName();
        }
        // 店铺分类
        CategoryVO shopCategoryVO = categoryMap.get(spuExcelVO.getShopCategoryId());
        if (Objects.nonNull(shopCategoryVO)) {
            shopCategoryName = shopCategoryVO.getName();
        }
        String delivery = spuExcelVO.getDeliveryMode();
        delivery = delivery.substring(0, delivery.length() - 1);
        for (SupplierSpuExcelVO spuExcel : skuData) {
            spuExcel.setPriceFee(conversionPrices(spuExcel.getPriceFee()));
            spuExcel.setMarketPriceFee(conversionPrices(spuExcel.getMarketPriceFee()));
            spuExcel.setSeq(spuExcelVO.getSeq());
            spuExcel.setDeliveryTemplate(spuExcelVO.getDeliveryTemplate());
            spuExcel.setBrandName(brandName);
            spuExcel.setNameZh(spuExcelVO.getNameZh());
            spuExcel.setSellingPointZh(spuExcelVO.getSellingPointZh());
            spuExcel.setCategoryName(categoryName);
            spuExcel.setShopCategoryName(shopCategoryName);
            spuExcel.setDeliveryMode(delivery);
            spuExcel.setStatus(spuExcelVO.getStatus());
            spuExcel.setCommissionSpuStatus(spuExcelVO.getCommissionSpuStatus());
            spuExcel.setSupplierDelivery(spuExcelVO.getSupplierDelivery());
            spuExcel.setSupplyPrice(conversionPrices(spuExcel.getSupplyPrice()));
            spuExcel.setSupplierName(spuExcelVO.getSupplierName());
            spuExcelList.add(spuExcel);
        }
    }

    /**
     * 获取spu信息
     *
     * @param spuList
     * @param spu
     * @param categoryMap     平台分类
     * @param shopCategoryMap 店铺分类
     * @param transportMap    运费模板
     * @param brandMap        品牌
     */
    private void loadSpuData(List<SpuExcelVO> spuList, SpuDTO spu, Map<String, Long> categoryMap, Map<String, Long> shopCategoryMap,
                             Map<String, Long> transportMap, Map<String, List<BrandLang>> brandMap, Map<Integer, List<String>> errorMap) {
        Integer sysType = AuthUserContext.get().getSysType();
        boolean init = false;
        List<SkuDTO> skuList = new ArrayList<>();
        for (SpuExcelVO spuExcelVO : spuList) {
            if (!init) {
                if (StrUtil.isBlank(spuExcelVO.getNameZh())) {
                    addSpuExcelError(errorMap, SpuExportError.SPU_NAME, spuExcelVO.getSeq());
                    return;
                }
                spu.setSpuCode(Objects.nonNull(spuExcelVO.getSpuCode()) ? spuExcelVO.getSpuCode() : null);
                spu.setSpuLangList(new ArrayList<>());
                spu.getSpuLangList().add(new SpuLangDTO(LanguageEnum.LANGUAGE_ZH_CN.getLang(), spuExcelVO.getNameZh(), spuExcelVO.getSellingPointZh()));
//                if (StrUtil.isNotBlank(spuExcelVO.getNameEn()) || StrUtil.isNotBlank(spuExcelVO.getSellingPointEn())) {
//                    spu.getSpuLangList().add(new SpuLangDTO(LanguageEnum.LANGUAGE_EN.getLang(), spuExcelVO.getNameEn(), spuExcelVO.getSellingPointEn()));
//                }
                spu.setBrandId(handleBrand(brandMap.get(spuExcelVO.getBrandName())));
                // 平台分类
                Long categoryId = categoryMap.get(spuExcelVO.getCategoryName());
                if (Objects.isNull(categoryId)) {
                    addSpuExcelError(errorMap, SpuExportError.PLATFORM_CATEGORY, spuExcelVO.getSeq());
                    return;
                }
                spu.setCategoryId(categoryId);
                // 店铺分类
                Long shopCategoryId = shopCategoryMap.get(spuExcelVO.getShopCategoryName());
                //供应商没有店铺分类
                if (Objects.equals(sysType, SysTypeEnum.SUPPLIER.value())) {
                    spu.setShopCategoryId(-1L);
                    spu.setSupplierSpuType(SupplierSpuType.YES.value());
                } else {
                    if (Objects.isNull(shopCategoryId)) {
                        addSpuExcelError(errorMap, SpuExportError.SHOP_CATEGORY, spuExcelVO.getSeq());
                        return;
                    }
                    spu.setShopCategoryId(shopCategoryId);
                    spu.setSupplierSpuType(SupplierSpuType.NO.value());
                }
                // 虚拟商品信息
                if (Objects.equals(spuExcelVO.getIsRefund(), YES)) {
                    spu.setIsRefund(1);
                } else {
                    spu.setIsRefund(0);
                }
                if (Objects.equals(spuExcelVO.getSpuMold(), PHYSICAL_SPU)) {
                    spu.setSpuMold(0);
                    spu.setIsRefund(1);
                    spu.setVirtualRemark(null);
                    if (StrUtil.contains(spuExcelVO.getDeliveryMode(), DeliveryType.NOT_DELIVERY.description())) {
                        addSpuExcelError(errorMap, SpuExportError.DELIVERY_TYPE, spuExcelVO.getSeq());
                        return;
                    }
                } else if (Objects.equals(spuExcelVO.getSpuMold(), VIRTUAL_SPU)) {
                    spu.setSpuMold(1);
                    String writeOffNum = spuExcelVO.getWriteOffNum();
                    String writeOffTime = spuExcelVO.getWriteOffTime();
                    if (Objects.isNull(writeOffNum) || Objects.isNull(writeOffTime)) {
                        addSpuExcelError(errorMap, SpuExportError.VIRTUAL_DATA, spuExcelVO.getSeq());
                        return;
                    }
                    if (Objects.equals(writeOffNum, REPEATEDLY)) {
                        spu.setWriteOffNum(-1);
                        spu.setWriteOffMultipleCount(StrUtil.equals(spuExcelVO.getWriteOffMultipleCount(), UNLIMITED) ? -1 : Integer.parseInt(spuExcelVO.getWriteOffMultipleCount().replace("次", "")));
                    } else if (Objects.equals(writeOffNum, WITHOUT)) {
                        spu.setWriteOffNum(0);
                    } else if (Objects.equals(writeOffNum, SINGLE)) {
                        spu.setWriteOffNum(1);
                    }
                    if (StrUtil.equals(writeOffTime, CUSTOMIZATION)) {
                        spu.setWriteOffTime(0);
                    } else if (writeOffTime.contains("天")) {
                        spu.setWriteOffTime(Integer.parseInt(spuExcelVO.getWriteOffTime().replace("天", "")));
                    } else if (StrUtil.equals(writeOffTime, LongTerm)) {
                        spu.setWriteOffTime(-1);
                    } else {
                        spu.setWriteOffTime(Integer.parseInt(writeOffTime));
                    }
                    spu.setWriteOffStart(spuExcelVO.getWriteOffStart());
                    spu.setWriteOffEnd(spuExcelVO.getWriteOffEnd());
                    spu.setVirtualRemark(spuExcelVO.getVirtualRemark());
                    spu.setDeliveryMode(DeliveryType.NOT_DELIVERY.description());
                }
                spu.setDeliveryMode(getDeliveryMode(spuExcelVO.getDeliveryMode()));
                spu.setPreSaleType(Objects.isNull(spu.getPreSaleType()) ? -1 : spu.getPreSaleType());
                // 运费模板
                Long deliveryTemplateId = transportMap.get(spuExcelVO.getDeliveryTemplate());
                if (Objects.isNull(deliveryTemplateId) && !Objects.equals(spu.getSpuMold(), 1)) {
                    addSpuExcelError(errorMap, SpuExportError.DELIVER, spuExcelVO.getSeq());
                    return;
                }
                spu.setDeliveryTemplateId(deliveryTemplateId);

                spu.setPriceFee(Constant.MIN_SPU_AMOUNT);
                spu.setMarketPriceFee(Constant.MIN_SPU_AMOUNT);
                if (Objects.equals(spuExcelVO.getStatus(), ENABLE)) {
                    spu.setStatus(StatusEnum.ENABLE.value());
                } else {
                    spu.setStatus(StatusEnum.DISABLE.value());
                }
                spu.setMainImgUrl(StrUtil.isNotBlank(spuExcelVO.getImgs()) ? spuExcelVO.getImgs().split(",")[0] : "");
                spu.setImgUrls(StrUtil.isNotBlank(spuExcelVO.getImgs()) ? spuExcelVO.getImgs() : "");
                spu.setVideo(spuExcelVO.getVideo());
                spu.setHasSkuImg(0);
                spu.setSpuType(SpuType.NORMAL.value());
                spu.setIsCompose(0);
                spu.setSeq(1);
                spu.setScoreFee(Constant.ZERO_LONG);
                if (Objects.isNull(spu.getSpuMold())) {
                    spu.setSpuMold(0);
                }
                init = true;
            }
            SkuDTO sku;
            try {
                //多规格商品  销售属性不能为空
                if (skuList.size() > 0 && StrUtil.isBlank(spuExcelVO.getPropertiesZh())) {
                    addSpuExcelError(errorMap, SpuExportError.PROPERTIES, spuExcelVO.getSeq());
                }
                sku = loadSkuData(spuExcelVO, spu, errorMap);
            } catch (Exception e) {
                if (!Objects.equals(e.getMessage(), ResponseEnum.DATA_ERROR.value())) {
                    addSpuExcelError(errorMap, SpuExportError.PRODUCT_DATA, spuExcelVO.getSeq());
                }
                return;
            }
            skuList.add(sku);
        }
        spu.setSkuList(skuList);
        // 售价最小的sku，决定spu的售价以及市场价
        Long priceFee = Long.MAX_VALUE;
        Long marketPriceFee = Constant.MIN_SPU_AMOUNT;
        for (SkuDTO sku : skuList) {
            if (sku.getPriceFee() < priceFee) {
                priceFee = sku.getPriceFee();
                marketPriceFee = sku.getMarketPriceFee();
            }
        }
        if (priceFee == Long.MAX_VALUE) {
            priceFee = Constant.MIN_SPU_AMOUNT;
        }
        spu.setPriceFee(priceFee);
        spu.setMarketPriceFee(marketPriceFee);
        // 保存商品信息
        spuService.save(spu);
    }

    private Long handleBrand(List<BrandLang> brandLangList) {
        if (CollUtil.isEmpty(brandLangList)) {
            return null;
        }
        if (brandLangList.size() > 1) {
            brandLangList.sort(Comparator.comparing(BrandLang::getLang).thenComparing(BrandLang::getBrandId).reversed());
        }
        return brandLangList.get(0).getBrandId();
    }


    /**
     * 获取spu配送类型信息
     *
     * @param data
     * @return
     */
    private String getDeliveryMode(String data) {
        SpuVO.DeliveryModeVO deliveryModeVO = new SpuVO.DeliveryModeVO();
        // 默认支持快递
        deliveryModeVO.setHasShopDelivery(Boolean.TRUE);
        deliveryModeVO.setHasCityDelivery(StrUtil.contains(data, DeliveryType.SAME_CITY.description()));
        deliveryModeVO.setHasUserPickUp(StrUtil.contains(data, DeliveryType.STATION.description()));
        return Json.toJsonString(deliveryModeVO);
    }

    /**
     * 获取sku数据
     *
     * @param spuExcelVO
     * @param spu
     * @param errorMap
     * @return
     */
    private SkuDTO loadSkuData(SpuExcelVO spuExcelVO, SpuDTO spu, Map<Integer, List<String>> errorMap) {
        spu.setTotalStock(0);
        SkuDTO sku = new SkuDTO();
        sku.setSkuLangList(new ArrayList<>());
        StrUtil.isNotBlank(sku.getSkuName());
        sku.setPriceFee(conversionPricesToLong(spuExcelVO.getPriceFee()));
        sku.setMarketPriceFee(conversionPricesToLong(spuExcelVO.getMarketPriceFee()));
        sku.setStatus(StatusEnum.ENABLE.value());
        sku.setStock(getStock(spuExcelVO.getStock()));
        spu.setTotalStock(spu.getTotalStock() + sku.getStock());
        sku.setPartyCode(spuExcelVO.getPartyCode());
//        sku.setModelId(spuExcelVO.getModelId());
        sku.setWeight(spuExcelVO.getWeight());
        sku.setVolume(spuExcelVO.getVolume());
        sku.setStockWarning(spuExcelVO.getStockWarning());
        sku.setScoreFee(Constant.ZERO_LONG);
        if (sku.getPriceFee() < spu.getPriceFee()) {
            spu.setPriceFee(sku.getPriceFee());
        }
        if (sku.getMarketPriceFee() < spu.getMarketPriceFee()) {
            spu.setMarketPriceFee(sku.getMarketPriceFee());
        }
        boolean blankSkuNameZh = StrUtil.isBlank(spuExcelVO.getSkuNameZh());
        boolean blankPropertiesZh = StrUtil.isBlank(spuExcelVO.getPropertiesZh());
        if (blankSkuNameZh && blankPropertiesZh) {
            return sku;
        }
        // 属性值及sku名称状态必须一致（都为空，或都有值）
        else if (!Objects.equals(blankPropertiesZh, blankSkuNameZh)) {
            addSpuExcelError(errorMap, blankPropertiesZh ? SpuExportError.SKU_NAME : SpuExportError.PROPERTIES, spuExcelVO.getSeq());
            throw new LuckException(ResponseEnum.DATA_ERROR);
        }


        sku.setSpuSkuAttrValues(new ArrayList<>());
        String[] propertiesZh = spuExcelVO.getPropertiesZh().split(Constant.SEMICOLON);
        StringBuilder attrsZh = new StringBuilder();
        StringBuilder attrsEn = new StringBuilder();
        for (int i = 0; i < propertiesZh.length; i++) {
            SpuSkuAttrValueDTO spuSkuAttrValue = new SpuSkuAttrValueDTO();
            spuSkuAttrValue.setSpuSkuAttrValueLangList(new ArrayList<>());
            setSpuSkuAttrValueLang(spuSkuAttrValue, propertiesZh[i], attrsZh, LanguageEnum.LANGUAGE_ZH_CN.getLang());

            sku.getSpuSkuAttrValues().add(spuSkuAttrValue);
        }
        attrsZh.deleteCharAt(attrsZh.lastIndexOf(Constant.COMMA));
        // sku国际化信息
        sku.getSkuLangList().add(new SkuLangDTO(LanguageEnum.LANGUAGE_ZH_CN.getLang(), spuExcelVO.getSkuNameZh(), attrsZh.toString()));


        return sku;
    }

    /**
     * 插入属性数据
     *
     * @param spuSkuAttrValue
     * @param property
     * @param attrs
     * @param lang
     */
    private void setSpuSkuAttrValueLang(SpuSkuAttrValueDTO spuSkuAttrValue, String property, StringBuilder attrs, Integer lang) {
        String[] attr = property.split(Constant.COLON);
        attrs.append(attr[0] + Constant.COMMA);
        SpuSkuAttrValueLangDTO spuSkuAttrValueLangDTO = new SpuSkuAttrValueLangDTO();
        spuSkuAttrValueLangDTO.setLang(lang);
        spuSkuAttrValueLangDTO.setAttrName(attr[0]);
        spuSkuAttrValueLangDTO.setAttrValueName(attr[1]);
        spuSkuAttrValue.getSpuSkuAttrValueLangList().add(spuSkuAttrValueLangDTO);
    }

    /**
     * 获取sku库存
     *
     * @param stock
     * @return
     */
    private Integer getStock(Integer stock) {
        Integer minStock = 0;
        if (Objects.isNull(stock) || stock < minStock) {
            return minStock;
        }
        return stock;
    }

    /**
     * 金额Long格式转换Double
     *
     * @param num
     * @return 金额字符串
     */
    private String conversionPrices(String num) {
        if (StrUtil.isBlank(num)) {
            return num;
        }
        BigDecimal b1 = new BigDecimal(num);
        BigDecimal b2 = new BigDecimal(Constant.PRICE_MAGNIFICATION);
        double price = b1.divide(b2, 2, BigDecimal.ROUND_HALF_UP).doubleValue();
        return Double.toString(price);
    }

    /**
     * 金额Double格式转换Long
     *
     * @param num
     * @return
     */
    private Long conversionPricesToLong(String num) {
        long amount;
        try {
            amount = Math.round(Arith.mul(Double.parseDouble(num), Constant.PRICE_MAGNIFICATION));
            if (amount < Constant.MIN_SPU_AMOUNT) {
                amount = Constant.MIN_SPU_AMOUNT;
            }
            if (amount > Constant.MAX_SPU_AMOUNT) {
                amount = Constant.MAX_SPU_AMOUNT;
            }
        } catch (Exception e) {
            amount = Constant.MIN_SPU_AMOUNT;
        }
        return amount;
    }
}
